/*
 * timedmonitor.hpp
 *
 *  Created on: 2019-1-9
 *      Author: work
 */

#ifndef _DM_SESSION_TIMEDMONITOR_HPP_
#define _DM_SESSION_TIMEDMONITOR_HPP_

#include <dm/session/common.hpp>
#include <dm/timestamp.hpp>

#include <dm/scada/eventmonitor.hpp>
#include <dm/scada/timedmeasuremonitor.hpp>
#include <dm/scada/timedcumulantmonitor.hpp>

#include <dm/bitsref.hpp>

namespace dm{
namespace session{

/**
 * 时标数据监视器
 */
class CTimedMonitor{
	CTimedMonitor(const CTimedMonitor&);
public:
	/**
	 * 通用的位置指针。实际程序不使用
	 */
	typedef dm::CRingPos<dm::uint16,dm::uint16,1024> ringpos_t;

	/**
	 * 时标数据类型
	 */
	enum EType{
		Unknow,
		Event,        //!< Event 事件
		TimedMeasure, //!< TimedMeasure 测量量
		TimedCumulant,//!< TimedCumulant 累计量
		Action        //!< Action 动作
	};

	/**
	 * 事件类型
	 */
	enum EEventType{
		EtNone,
		EtStatus,  //!< EtStatus
		EtDiscrete,//!< EtDiscrete
		EtMeasure  //!< EtMeasure
	};

	enum{
		Filter_MaxDevice = 10,
		Filter_MaxStatusLevel = 10
	};

public:
	CTimedMonitor();

	bool isIdle( const dm::CTimeStamp& n )const;

	bool isTimeout( const dm::CTimeStamp& n )const;

	inline const dm::CTimeStamp& deadline()const{
		return m_deadline;
	}

	inline void setDeadline( const dm::CTimeStamp& ts ){
		m_deadline = ts;
	}

	inline const mod_t& mod()const{
		return m_mod;
	}

	inline void setMod( const mod_t& m ){
		m_mod = m;
	}

	inline const EType& type()const{
		return m_type;
	}

	inline void setType( const EType& t ){
		m_type = t;
	}

	inline void setFilterDevice( const int& i,const dm::scada::index_t& idx ){
		m_deviceFilter[i] = idx;
	}

	inline const dm::scada::index_t& filterDevice( const int& i )const{
		return m_deviceFilter[i];
	}

	inline void setFilterStatusLevel( const int& i,const int& level ){
		m_statusLevelFilter[i] = level;
	}

	inline const int& filterStatusLevel( const int& i )const{
		return m_statusLevelFilter[i];
	}

	inline void resetEventType(){
		m_eventTypeFilter = 0;
	}

	inline bool ifEventNone()const{
		return dm::CBitsRef<const dm::uint8>(m_eventTypeFilter).isSet(EtNone);
	}

	inline bool ifEventStatus()const{
		return dm::CBitsRef<const dm::uint8>(m_eventTypeFilter).isSet(EtStatus);
	}

	inline bool ifEventDiscrete()const{
		return dm::CBitsRef<const dm::uint8>(m_eventTypeFilter).isSet(EtDiscrete);
	}

	inline bool ifEventMeasure()const{
		return dm::CBitsRef<const dm::uint8>(m_eventTypeFilter).isSet(EtMeasure);
	}

	inline void setEventNone(){
		dm::CBitsRef<dm::uint8>(m_eventTypeFilter).set(EtNone);
	}

	inline void clrEventNone(){
		dm::CBitsRef<dm::uint8>(m_eventTypeFilter).clr(EtNone);
	}

	inline void setEventStatus(){
		dm::CBitsRef<dm::uint8>(m_eventTypeFilter).set(EtStatus);
	}

	inline void clrEventStatus(){
		dm::CBitsRef<dm::uint8>(m_eventTypeFilter).clr(EtStatus);
	}

	inline void setEventDiscrete(){
		dm::CBitsRef<dm::uint8>(m_eventTypeFilter).set(EtDiscrete);
	}

	inline void clrEventDiscrete(){
		dm::CBitsRef<dm::uint8>(m_eventTypeFilter).clr(EtDiscrete);
	}

	inline void setEventMeasure(){
		dm::CBitsRef<dm::uint8>(m_eventTypeFilter).set(EtMeasure);
	}

	inline void clrEventMeasure(){
		dm::CBitsRef<dm::uint8>(m_eventTypeFilter).clr(EtMeasure);
	}

	dm::scada::CEventMonitor::ringpos_t* eventPos();
	dm::scada::CTimedMeasureMonitor::ringpos_t* measurePos();
	dm::scada::CTimedCumulantMonitor::ringpos_t* cumulantPos();

private:
	dm::CTimeStamp m_deadline;
	mod_t m_mod;
	EType m_type;

	/**
	 * 设备过滤器
	 */
	dm::scada::index_t m_deviceFilter[Filter_MaxDevice];

	/**
	 * 状态量级别过滤器
	 * -1 表示不过滤
	 */
	int m_statusLevelFilter[Filter_MaxStatusLevel];

	/**
	 * 事件类型过滤器
	 */
	dm::uint8 m_eventTypeFilter;


	ringpos_t m_pos;
};

}
}

#endif /* INCLUDE_DM_SESSION_TIMEDMONITOR_HPP_ */
